/*
 * @Author: Dannycjh 2233879049@qq.com
 * @Date: 2023-04-15 11:57:11
 * @LastEditors: Dannycjh 2233879049@qq.com
 * @LastEditTime: 2023-04-28 14:47:26
 * @FilePath: \cc-game-development-template\assets\game.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
/*
 * @Author: Dannycjh 2233879049@qq.com
 * @Date: 2023-04-15 11:57:11
 * @LastEditors: Dannycjh 2233879049@qq.com
 * @LastEditTime: 2023-04-17 09:04:56
 * @FilePath: \cc-game-development-template\assets\scripts\game.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import { _decorator, Node, Prefab, resources, tween, Vec3, instantiate, find, MeshRenderer } from 'cc';
import { App } from '../../../App';
import UtilTool from '../../../tools/UtilTool';
import BilliardsGameController from '.././controller/BilliardsGameController';
import { Ball } from '../Ball';
import { GameLayer4 } from './GameLayer4';
import { GameBaseModel } from '../GameBaseModel';
import { EndLayer4 } from './EndLayer4';
import { FOUR_BALL_BASE } from '../GameManage';
import { GameFourLogic } from './GameFourLogic';
import { GamePlayState } from '../GameBaseLogic';
import { Role } from '../Role';
import { PD } from '../../../player/PlayerData';
import { showGameFourMora } from '../../../tools/PopuUp';
import { Material } from 'cc';
import { Vec2 } from 'cc';
const { ccclass, property } = _decorator;

// 游戏主脚本
@ccclass('GameModel4')
export class GameModel4 extends GameBaseModel {
    @property(Prefab)
    GameMoraPrefab : Prefab = null;   // 猜拳预制体

    @property(Material)
    bgdeskMaterial : Material = null;   // 背景图

    gameLayerCtrl = null
    gameLogic : GameFourLogic = null
    moraPanel:Node = null    // 猜拳界面

    frameHz = 6     // 帧同步请求频率 (频率越小，同步越频繁)
    frameCount = 0  // 帧数
    whiteBallNumber = FOUR_BALL_BASE    // 母球的球号
    
    protected onLoad(): void {
        super.onLoad();
    }

    protected onEnable(): void {
        super.onEnable();
    }
    
    start() {
        super.start();
        App.WSGameStatus = 3
        this.gameLayerCtrl = this.getGameLayerCtrl(GameLayer4)
        this.gameLogic = new GameFourLogic()

        let bgdeskNode = find('gameNode/game_3d/bg_desk')
        let bgdeskmeshRenderer:MeshRenderer = bgdeskNode.getComponent(MeshRenderer)
        bgdeskmeshRenderer.setMaterial(this.bgdeskMaterial, 0);

        // this.cueCtrl.showCue(false,this.cueCtrl.ballToCueAngle(this.getWhiteToOneAngle()))
        this.setAllBallShow(false)

        tween(this.node).delay(0.1).call(()=>{
            this.gameLogic.initGame()
        }).start()
        if ((App.Model.gameManage.isReconnectAndGameing() && App.Model.gameManage.isReconnectAndGameing().currentRoomStatus==2)
        || (App.Model.gameManage.isWatchGame && App.Model.gameManage.gameWatchData.currentRoomStatus==2)){
            tween(this.node).delay(0.11).call(()=>{
                this.setAllBallShow(true)
                this.gameLogic.setPlayState(GamePlayState.GAME_START)
            }).start()
        }
        else{
            this.showMoraPanel()
        }
    }
    
    /**
     * 游戏开始
     */
    gameStart() {
        if (App.Model.gameManage.isReconnectAndGameing() && App.Model.gameManage.isReconnectAndGameing().currentRoomStatus==2) {
            this.gameLogic.respGameReconnect(App.Model.gameManage.gameReconnectData.fourBallInfo)
        }
        else if (App.Model.gameManage.isWatchGame && App.Model.gameManage.gameWatchData.currentRoomStatus==2) {
            this.gameLogic.respGameReconnect(App.Model.gameManage.gameWatchData.fourBallInfo)
        }
        else{
            // this.cueCtrl.showCue(false,this.cueCtrl.ballToCueAngle(this.getWhiteToOneAngle()))

        }
    }

    /**  
     * 显示猜拳界面
    */
    showMoraPanel() {
        // this.moraPanel = showGameFourMora(this.viewNode)
        this.moraPanel = instantiate(this.GameMoraPrefab)
        this.moraPanel.parent = this.viewNode
    }

    // 初始化四球开伦台球，台球一字型排列
    initTableBallsFour() {
        App.Model.gameManage.otherBallArr = []
        App.Model.gameManage.otherBallArrUI = []

        for(let i=1; i<=3; i++) {
            let ball = instantiate(this.ballPrefab);
            this.node.addChild(ball);

            ball.getComponent(Ball).init(i+FOUR_BALL_BASE);
            App.Model.gameManage.otherBallArr.push(ball)
        }

        this.resetAllBallPosFour(false)
    }

    /**  
     * 重新摆球
     * @param isMine 是否是自己击打
    */
    resetAllBallPosFour(isMine=true) {
        this.setBallSleep(this.whiteBall)
        this.whiteBall.position = new Vec3(-60, 1, 0);
        
        this.whiteBall.getComponent(Ball).init(FOUR_BALL_BASE);
        this.whiteBall.getComponent(Ball).setDefault();
        this.whiteBall.active = true

        for(let i=1; i<=3; i++) {
            let ball = this.getBallByNumber(i+FOUR_BALL_BASE, this.whiteBallNumber)
            this.setBallSleep(ball)

            let x = -60 + i*40
            let pos = new Vec3(x, 1, 0);
    
            ball.node.setPosition(pos);
            ball.node.active = true
            ball.setDefault()
        }
        
        this.cueCtrl.showCue(isMine)
    }

    // 设置球显示隐藏
    setAllBallShow(show=true) {
        if (show) {
            this.whiteBall.active = true
            App.Model.gameManage.otherBallArr.forEach(item => {
                item.active = true
            });
        }
        else{
            this.whiteBall.active = false
            App.Model.gameManage.otherBallArr.forEach(item => {
                item.active = false
            });
        }
    }

    // 切换母球
    switchMotherBall(motherNumber) {
        if (this.whiteBall.getComponent(Ball).number==motherNumber) {
            return
        }

        let newPos = new Vec3(0,0,0)
        let oldPos = new Vec3(0,0,0)
        oldPos.x = this.whiteBall.worldPosition.x
        oldPos.y = this.whiteBall.worldPosition.y
        oldPos.z = this.whiteBall.worldPosition.z
        let oldNumber = this.whiteBall.getComponent(Ball).number

        for (let i = 0; i < App.Model.gameManage.otherBallArr.length; i++) {
            let ball = App.Model.gameManage.otherBallArr[i];
            let ballCtrl = ball.getComponent(Ball)
            if (ballCtrl.number == motherNumber) {
                newPos.x = ball.worldPosition.x
                newPos.y = ball.worldPosition.y
                newPos.z = ball.worldPosition.z

                // ball.worldPosition = new Vec3(oldPos.x, -10, oldPos.z)
                ball.active = false
                this.whiteBall.getComponent(Ball).init(motherNumber)
                this.whiteBall.worldPosition = newPos

                ball.getComponent(Ball).init(oldNumber)
                ball.worldPosition = oldPos
                ball.active = true
                break
            }
        }
    }


    // 收到球进洞事件
    ballInRoleEvent(ballNumber : number, ballNode : Node, role : Role) {
        if  (!this.node) return;
        this.gameLogic.ballInRoleEvent(ballNumber, ballNode, role)
    }

    // 收到开始击球事件
    startHitBallEvent(event) {
        UtilTool.printLog("GameModel1 start hit ball")
        this.gameLogic.startHitBallEvent(event)
        this.frameCount = this.frameHz
    }
    
    // 收到白球碰撞球事件
    whiteBallContactEvent(ballNumber : number) {
        UtilTool.printLog("GameModel4 收到白球碰撞球事件")
        this.isOpenBallStatus = false
        if(!this.gameLogic) {
            return // 游戏开始时会有碰球的情况
        }

        this.gameLogic.whiteBallContactEvent(ballNumber)

    }

    // 收到摆球结束事件
    whiteBallPosEndEvent(whiteBallPos) {
        UtilTool.printLog("GameModel1 white ball pos end", whiteBallPos)
        this.gameLogic.whiteBallPosEndEvent(whiteBallPos)
    }

    // 收到击球结束事件
    hitBallEndEvent() {
        this.gameLogic.hitBallEndEvent()
        
    }

    update(deltaTime: number) {
        super.update(deltaTime)

        this.frameCount = this.frameCount + 1

        // 当前玩家是自己，并且是在击球的状态则上报帧同步
        if (this.frameCount >= this.frameHz) {
            if (this.gameLogic.curPlayUser && this.gameLogic.isMineAccount(this.gameLogic.uploadAccount) && this.gameLogic.curPlayState==GamePlayState.HIT_BALL) {
                this.frameCount = 0
                this.reqFrameDataMsg()
            }
        }
        
    }

    /////////////////////////////////////////////////////////////// 请求消息 ////////////////////////////////////////////////////////////////////
    /**
     * 请求认输
     */
    reqGiveUpMsg(cb) {
        let controller = this.controller as BilliardsGameController
        controller.reqGiveUpMsg(cb)
    }

    /**
     * 请求客户端开球
     */
    reqOpenBallMsg(allBallInfo) {
        let controller = this.controller as BilliardsGameController
        controller.reqOpenBallMsg(allBallInfo)
    }

    /**
     * 请求调整球杆角度
     */
    reqChangeCueMsg(cueAngle) {
        let controller = this.controller as BilliardsGameController
        controller.reqChangeCueMsg(cueAngle)
    }

    /**
     * 请求玩家击球
     * @param cueAngle 球的角度
     * @param dynamics 力度
     */
    reqHitballMsg(angle, dynamics) {
        let controller = this.controller as BilliardsGameController
        controller.reqHitballMsg(angle, dynamics)
    }

    /** 
     * 请求上报帧数据
     */
    reqFrameDataMsg() {
        let controller = this.controller as BilliardsGameController
        let allBallInfo = this.gameLogic.getAllBallPos()
        controller.reqFrameDataMsg(allBallInfo)
    }

    /**
     * 请求退出观战
     */
    reqQuitWatchMsg() {
        let controller = this.controller as BilliardsGameController
        controller.reqQuitWatchMsg()
    }

    /**
     * 请求球桌运动结束，上报击球结果（四球开伦）
     * @param wheel 轮数,标识着是上传的第几轮的击球结果
     * @param hitBallNum 碰撞到的球号
     * @param allBallInfo 各个球的信息
     */
    reqHitballEndFourMsg(wheel, hitBallNum, allBallInfo) {
        if (this.gameLogic.curPlayState == GamePlayState.GAME_END) {
            return
        }
        let controller = this.controller as BilliardsGameController
        controller.reqHitballEndFourMsg(wheel, hitBallNum, allBallInfo)
    }
    
    
    /////////////////////////////////////////////////////////////// 请求消息 ////////////////////////////////////////////////////////////////////


    /**
     * 游戏结束
     */
    public gameOver(data) {
        resources.load('prefabs/game/layer4/GameEndLayer4',Prefab,(err,prefabs) =>{
            let layerNode = instantiate(prefabs);
            this.viewNode.addChild(layerNode);

            if (PD.user.addressUrl == data.winPlayerAccount) {
                layerNode.getComponent(EndLayer4).showView(data, 1)
            }
            else {
                layerNode.getComponent(EndLayer4).showView(data, 2)
            }
        })
    }

    onDestroy() {
        App.WSGameStatus = 0
    }

}

